/**
 * Created by scutterry on 16/3/4.
 */
class LoaderManager{

    private loadList:any;
    private isLoading:boolean;
    private resPath:string;


    private loadingConfigDic:any;
    private currentConfigUrl:string;

    private configDic:any;

    private resourceUrl:string;


    private loadingDic:any;

    public isShowLoading:boolean = false;


    public constructor(){
        this.loadList = [];
        this.isLoading = false;
        this.configDic = {};
        this.loadingDic = {};
        this.loadingConfigDic = {};
    }

    private static instance:any;
    public static getInstance():LoaderManager{
        if(!LoaderManager.instance){
            LoaderManager.instance = new LoaderManager();
        }

        return LoaderManager.instance;
    }

    /**
     * 初始化
     * @param resPath 资源相对路径，用于 CDN 部署
     */
    public init(resPath:string):void{
        this.resPath = resPath;
        this.resourceUrl = resPath
        RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onGroupComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onProgress, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onGroupError, this);
        RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemError, this);
    }



    private onGroupComplete(event:RES.ResourceEvent):void{
        console.log(event.groupName, "loaded");
        this.isLoading = false;

        var obj:any = this.loadingDic[event.groupName];
        if(obj){
            this.loadingDic[event.groupName] = undefined;
            if(typeof obj.func === "function"){
                obj.func.apply(obj.thisArg);
            }
        }

        if(this.loadList.length > 0){
            this.showLoadingMC();
            obj = this.loadList.shift();
            this.loadGroup(obj.groupName, obj.func, obj.thisArg, obj.jsonUrl);
        }else {
            this.hideLoadingMC();
        }
    }

    private onProgress(event:RES.ResourceEvent):void{
        if(this.isShowLoading){
            var p:number =  Math.floor(event.itemsLoaded * 100 / event.itemsTotal);
            setProgress(p);
        }
    }

    private onGroupError(event:RES.ResourceEvent):void{
        this.isLoading = false;
        console.log(event);
        alert("加载资源组错误" + event.groupName);
    }

    private onItemError(event:RES.ResourceEvent):void{
        this.isLoading = false;
        alert("onItemError 加载资源错误" + event.resItem.url);
    }

    private loadConfig(configUrl:string, func:any, thisArg:any):void{
        if(this.configDic[configUrl]){
            func.apply(thisArg);
            return;
        }
        var obj:any = {};
        obj.url = configUrl;
        obj.func = func;
        obj.thisArg = thisArg;
        this.loadingConfigDic[configUrl] = obj;
        RES.loadConfig(this.resPath + configUrl, this.resPath);
    }

    public showLoadingMC():void{
        playLoading();
    }

    private hideLoadingMC():void{
        stopLoading();
    }

    /**
     * 加载组
     * @param groupName
     * @param func
     * @param thisArg
     * @param jsonUrl
     */
    public loadGroup(groupName:string, func:any, thisArg:any, jsonUrl?:string):void{
        var waitObj:any = {};
        waitObj.groupName = groupName;
        waitObj.func = func;
        waitObj.thisArg = thisArg;

        //兼容版本号
        var resName:string = window['res_rev'];
        if (!jsonUrl) {
            if(resName && resName !== ""){
                jsonUrl = resName;
            }else {
                jsonUrl = "default.res.json";
            }
        }
        waitObj.jsonUrl = jsonUrl;

        console.log("load", groupName);

        if(this.isLoading){
            waitObj.jsonUrl = jsonUrl;
            this.loadList.push(waitObj);
        }else{
            this.loadingDic[groupName] = waitObj;

            if(this.configDic[jsonUrl]){
                this.isLoading = true;

                if(RES.isGroupLoaded(groupName)){
                    this.isLoading = false;
                    func.apply(thisArg);
                }else{
                    this.showLoadingMC();
                    RES.loadGroup(groupName);
                }
            }else {
                this.isLoading = true;
                this.currentConfigUrl = jsonUrl;
                this.loadList.push(waitObj);
                this.showLoadingMC();
                this.loadConfig(jsonUrl, function(){
                    RES.loadGroup(groupName);
                }, this);
            }
        }
    }

    private onConfigComplete(event:RES.ResourceEvent):void{
        console.log("config loaded", this.currentConfigUrl);
        if(this.currentConfigUrl && this.currentConfigUrl !== ""){
            this.configDic[this.currentConfigUrl] = 1;
            this.currentConfigUrl = undefined;
            this.isLoading = false;
            if(this.loadList.length > 0){
                this.showLoadingMC();
                var obj:any = this.loadList.shift();
                this.loadGroup(obj.groupName, obj.func, obj.thisArg, obj.jsonUrl);
            }else {
                this.hideLoadingMC();
                this.isLoading = false;
            }
        }else {
            this.currentConfigUrl = undefined;
            this.isLoading = false;
            console.log("just load config");
        }
    }



    public loadResUrl(url:string, func:any, thisArg:any, type:string):void{
        RES.getResByUrl(url, function(data){
            func.call(thisArg, data);
        }, this, type);
    }

    public loadRes(key:string, func:any, thisArg):void{
        RES.getResAsync(key, function(data){
            func.call(thisArg, data);
        }, this);
    }
}